package Core

import (
	"fmt"
	"database/sql"
	"strings"
	"log"
)

// declare global Db var
var Db *HxDatabase

// declare HxDatabase struct
type HxDatabase struct {
	sqlDb *sql.DB
}

// Get one result
func (this *HxDatabase) One(sqlStr string, args...interface {}) map[string]string {
	// if no limit keyword in sqlStr, add it
	if !strings.Contains(sqlStr, "LIMIT") {
		sqlStr = sqlStr + " LIMIT 1"
	}
	// query and return first one
	rs := this.All(sqlStr, args...)
	if len(rs) < 1 {
		return nil
	}
	return rs[0]
}

// Get many rows result
func (this *HxDatabase) All(sqlStr string, args...interface {}) []map[string]string {
	// query rows
	rows, e := this.sqlDb.Query(sqlStr, args...)
	if e != nil {
		panic(fmt.Sprint(e, " ", sqlStr))
	}
	// close rows
	defer rows.Close()
	// get columns
	rs, e2 := rowMapper(rows)
	if e2 != nil {
		panic(fmt.Sprint(e2, " ", sqlStr))
	}
	return rs
}

// Execute sql
// return last inserted id or affected rows count number
func (this *HxDatabase) Exec(sqlStr string, args...interface {}) int {
	rs , e := this.sqlDb.Exec(sqlStr, args...)
	if e != nil {
		panic(fmt.Sprint(e, " ", sqlStr))
		return -1
	}
	var i int64
	i, e = resultParser(rs)
	if e != nil {
		panic(fmt.Sprint(e, " ", sqlStr))
		return -1
	}
	return int(i)
}

// init global database
func newDatabase(driver string, dsn string, maxConnections int) {
	if len(driver) < 1 || len(dsn) < 1 {
		return
	}
	Db = &HxDatabase{}
	var e error
	Db.sqlDb, e = sql.Open(driver, dsn)
	if e != nil {
		panic(e)
	}
	Db.sqlDb.SetMaxIdleConns(maxConnections)
	log.Println("run database @ [" + driver + "]" + dsn)
}

